<?php

namespace Ysy\HyperfImport\Importer\Driver;

use Generator;
use League\Csv\Reader;
use League\Csv\Exception as CsvException;

class CsvDriver implements DriverInterface
{
    /**
     * 无类属性！所有配置通过参数传递，每次读取都是独立无状态的
     */
    public function read(
        string $filePath,
        string $extension, // CSV驱动暂用不到，但需实现接口参数
        bool $skipHeader = true,
        array $options = [],
        int &$totalCount = 0
    ): Generator {
        try {
            // 1. 从options提取配置（动态传递，无类属性依赖）
            $encoding = $options['encoding'] ?? 'UTF-8'; // 编码从参数取
            $delimiter = $options['delimiter'] ?? ','; // 支持自定义分隔符
            $enclosure = $options['enclosure'] ?? '"';

            // 2. 初始化CSV读取器（每次读取都是新实例）
            $csv = Reader::createFromPath($filePath, 'r');
            $csv->setDelimiter($delimiter);
            $csv->setEnclosure($enclosure);
            $csv->setEscape('\\');

            // 3. 编码转换（动态编码，无残留）
            if ($encoding !== 'UTF-8') {
                $csv->addFormatter(function (array $row) use ($encoding) {
                    return array_map(function ($value) use ($encoding) {
                        // 处理空值避免转换报错
                        return empty($value) ? '' : mb_convert_encoding($value, 'UTF-8', $encoding);
                    }, $row);
                });
            }

            // 4. 初始化计数和表头（每次读取重置计数）
            $totalCount = 0;
            $header = [];

            if ($skipHeader) {
                // 读取表头（不计数），处理空表头情况
                $header = $csv->fetchOne() ?: [];
                // 从下一行开始读数据
                $records = $csv->getRecords($header);
            } else {
                // 不跳过表头：表头作为第一条数据
                $records = $csv->getRecords();
            }

            // 5. 流式读取+计数（单协程顺序执行，无并发问题）
            foreach ($records as $record) {
                $totalCount++; // 实时累加计数
                yield [
                    'sheet_name' => 'CSV', // 固定标识，与Excel驱动格式对齐
                    'row_index' => $totalCount + ($skipHeader ? 1 : 0), // 行号（含表头）
                    'data' => $record, // 业务数据
                    'current_count' => $totalCount // 实时已读条数（供前端进度用）
                ];
            }

        } catch (CsvException $e) {
            throw new \RuntimeException("CSV读取失败：{$e->getMessage()}");
        } catch (\Exception $e) {
            throw new \RuntimeException("文件处理失败：{$e->getMessage()}");
        }
    }
}